Imports GMap.NET
Imports GMap.NET.WindowsForms
Imports GMap.NET.WindowsForms.Markers

''' <summary>
''' View stations locations using Google Maps control found at http://www.codeplex.com/gmap4dotnet
''' </summary>
Public Class frmGMap

    Private CenterPt As PointLatLng
    Private lyrStations As GMap.NET.WindowsForms.GMapOverlay

    Private Sub frmGMap_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        SaveWindowPos(REGAPP, Me)
        SaveSetting(REGAPP, Me.Name, "MapType", cboMapType.SelectedIndex)
        SaveSetting(REGAPP, Me.Name, "Zoom", trkZoom.Value)
    End Sub

    Private Sub frmGMap_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Try
            GetWindowPos(REGAPP, Me)
            With gMap
                .MarkersEnabled = True
                lyrStations = New GMap.NET.WindowsForms.GMapOverlay(gMap, "Stations")
                .Overlays.Add(lyrStations)
                .MouseWheelZoomType = MouseWheelZoomType.ViewCenter
                .DragButton = Windows.Forms.MouseButtons.Middle
                .IgnoreMarkerOnMouseWheel = True

                With cboMapType
                    .DropDownStyle = ComboBoxStyle.DropDownList
                    .MaxDropDownItems = 50
                    .Sorted = True
                    .Items.Clear()
                    For Each s As String In [Enum].GetNames(GetType(MapType))
                        If Not (s.Contains("China") Or
                                s.Contains("Korea") Or
                                s.Contains("Turkey") Or
                                s.Contains("Spain") Or
                                s.EndsWith("Ru") Or
                                s.Contains("Bender") Or
                                s.Contains("MapsLT") Or
                                s.Contains("SurferTerrain") Or
                                s.Contains("KarteLV") Or
                                s.Contains("MapyCZ") Or
                                s.Equals("None") Or
                                s.Contains("Yandex")) Then
                            .Items.Add(s.Replace("_", " "))
                        End If
                    Next
                    .SelectedIndex = GetSetting(REGAPP, Me.Name, "MapType", 0)
                End With

                With cboDisplay
                    .Items.Add("All Stations")
                    WRDBProject.ResetPDox("Stations")
                    .Items.AddRange(WRDBProject.DB.GetRecordList("Stations", "Station_Type").ToArray)
                    .SelectedIndex = 0
                    ReCenter()
                End With

                trkZoom.Value = GetSetting(REGAPP, Me.Name, "Zoom", 7)
            End With
        Catch ex As Exception
            ErrorMsg(, ex)
        End Try
    End Sub

    Private Sub trkZoom_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles trkZoom.ValueChanged
        Try
            With gMap
                .Zoom = trkZoom.Value + .MinZoom
            End With
        Catch ex As Exception
            ErrorMsg(, ex)
        End Try
    End Sub

    Private Sub cboMapType_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cboMapType.SelectedIndexChanged
        gMap.MapType = [Enum].Parse(GetType(MapType), cboMapType.Text.Replace(" ", "_"))
        gMap.Focus()
    End Sub

    Private Sub cboDisplay_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cboDisplay.SelectedIndexChanged
        Try
            Dim sumlat As Single = 0, sumlon As Single = 0, num As Integer = 0

            'MainForm.WriteProgress("Updating map...", ProgressBarStyle.Marquee)
            'gMap.ClearAllMarkers()
            lyrStations.Markers.Clear()

            Dim dr As DbDataReader = WRDBProject.DB.ExecuteReader("SELECT Station_ID,Station_Name,Latitude,Longitude FROM Stations" & IIf(cboDisplay.SelectedIndex = 0, "", " WHERE Station_Type='" & cboDisplay.Text & "'"))
            While dr IsNot Nothing And dr.Read
                Dim sta As String = TestNull(dr.GetValue(0), "")
                Dim nam As String = TestNull(dr.GetValue(1), "")
                Dim lat As Single = TestNull(dr.GetValue(2), 0)
                Dim lon As Single = -Math.Abs(TestNull(dr.GetValue(3), 0))
                If sta <> "" And Math.Abs(lat) > 0.5 And Math.Abs(lon) > 0.5 And Math.Abs(lat) < 90 And Math.Abs(lon) < 180 Then
                    sumlat += lat
                    sumlon += lon
                    num += 1
                    lyrStations.Markers.Add(New GMapMarkerStation(New PointLatLng(lat, lon), 0.7, sta & vbCrLf & nam))
                End If
                'If Not MainForm.WriteProgress("Preparing map...", ProgressBarStyle.Marquee) Then Exit While
            End While
            dr.Close()

            ' set initial map coordinates in Latitude,Longitude
            CenterPt = New PointLatLng(sumlat / num, sumlon / num)

            'MainForm.ProgressComplete()
            'gMap.ReloadMap()
        Catch ex As Exception
            ErrorMsg(, ex)
        End Try
    End Sub

    Private Sub ReCenter()
        gMap.Position = CenterPt
    End Sub

    Private Sub LocatePlace()
        Try
            If txtLocation.Text = "" Then Exit Sub
            'first, try to find stationid
            With gMap
                Dim dr As DbDataReader = WRDBProject.DB.ExecuteReader("SELECT LATITUDE,LONGITUDE FROM STATIONS WHERE STATION_ID='{0}'", txtLocation.Text.ToUpper.Trim)
                If dr IsNot Nothing AndAlso dr.Read Then
                    Dim lat As Single = TestNull(dr.GetValue(0), 0)
                    Dim lon As Single = -Math.Abs(TestNull(dr.GetValue(1), 0))
                    If lat < 1 Or lat > 90 Or Math.Abs(lon) < 1 Or Math.Abs(lon) > 180 Then
                        WarningMsg("Station ID {0} does not have valid values for latitude and longitude.", txtLocation.Text)
                    Else
                        .Position = New PointLatLng(lat, lon)
                        '.GoToCurrentPosition()
                    End If
                    dr.Close()
                Else
                    If .SetCurrentPositionByKeywords(txtLocation.Text) Then
                        '.GoToCurrentPosition()
                    Else
                        WarningMsg("That Station ID was not found and Google maps unable to find named place: " & txtLocation.Text)
                    End If
                End If
            End With
            txtLocation.Text = ""
        Catch ex As Exception
            ErrorMsg(, ex)
        End Try
    End Sub

    Private Sub btnLocation_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnLocation.Click
        LocatePlace()
    End Sub

    Private Sub frmGMap_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
        If txtLocation.Focused And e.KeyChar = Chr(13) Then
            LocatePlace()
            e.Handled = True
        End If
    End Sub

    Private Sub gMap_OnMapZoomChanged() Handles gMap.OnMapZoomChanged
        With gMap
            trkZoom.Value = Math.Max(trkZoom.Minimum, Math.Min(trkZoom.Maximum, .Zoom - .MinZoom))
        End With
    End Sub

    'Private Sub gMap_OnCurrentPositionChanged(ByVal point As GMapNET.PointLatLng) Handles gMap.OnCurrentPositionChanged

    'End Sub

    Private Sub gMap_OnMarkerClick(ByVal item As GMap.NET.WindowsForms.GMapMarker, e As MouseEventArgs) Handles gMap.OnMarkerClick
        Try
            'Dim sta As String = item.Text.Split(vbCr)(0)
            Dim sta As String = item.ToolTipText.Split(vbCr)(0)
            Dim dr As DbDataReader = WRDBProject.DB.ExecuteReader("SELECT * FROM STATIONS WHERE STATION_ID='{0}'", sta)
            If dr IsNot Nothing And dr.Read Then
                Dim s As String = ""
                For i As Integer = 0 To dr.FieldCount - 1
                    s &= (dr.GetName(i) & ":").PadRight(15) & vbTab & TestNull(dr.GetValue(i), "") & vbCr
                Next
                MessageBox.Show(s, "Station Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
            End If
            dr.Close()
        Catch ex As Exception
            ErrorMsg(, ex)
        End Try
    End Sub

    Public Sub New(ByVal _WRDBProject As WRDB.Project.clsProject)

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        WRDBProject = _WRDBProject
    End Sub

    Private Sub ToolStripButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripButton1.Click
        VB6.WhatsThisMode(Me)
    End Sub

    Private Sub picPanUp_Click(sender As System.Object, e As System.EventArgs) Handles picPanUp.Click
        With gMap
            .Position = New PointLatLng(.Position.Lat + .CurrentViewArea.HeightLat / 2, .Position.Lng)
        End With
    End Sub

    Private Sub picPanLt_Click(sender As System.Object, e As System.EventArgs) Handles picPanLt.Click
        With gMap
            .Position = New PointLatLng(.Position.Lat, .Position.Lng - .CurrentViewArea.WidthLng / 2)
        End With
    End Sub

    Private Sub picPanRt_Click(sender As System.Object, e As System.EventArgs) Handles PictureBox1.Click, picPanRt.Click
        With gMap
            .Position = New PointLatLng(.Position.Lat, .Position.Lng + .CurrentViewArea.WidthLng / 2)
        End With
    End Sub

    Private Sub picPanDn_Click(sender As System.Object, e As System.EventArgs) Handles picPanDn.Click
        With gMap
            .Position = New PointLatLng(.Position.Lat - .CurrentViewArea.HeightLat / 2, .Position.Lng)
        End With
    End Sub
End Class

Public Class GMapMarkerStation
    Inherits GMapMarker

    Private pen As Pen
    Private _ScaleFactor As Single

    Public Sub New(ByVal p As PointLatLng, ByVal ScaleFactor As Single, ByVal ToolTip As String)
        MyBase.new(p)
        pen = New Pen(Brushes.Red)
        _ScaleFactor = ScaleFactor
        Size = New Drawing.Size(My.Resources.blue_MarkerA.Size.Width * ScaleFactor, My.Resources.blue_MarkerA.Size.Height * ScaleFactor)
        Offset = New Drawing.Point(-Size.Width / 2, -Size.Height)
        ToolTipText = ToolTip
        ToolTipMode = WindowsForms.MarkerTooltipMode.OnMouseOver
    End Sub

    Public Overrides Sub OnRender(ByVal g As System.Drawing.Graphics)
        Dim img As Image = My.Resources.blue_MarkerA
        Dim p As Drawing.Point = MyBase.LocalPosition
        g.DrawImage(img, CSng(p.X), CSng(p.Y), img.Width * _ScaleFactor, img.Height * _ScaleFactor)
    End Sub

End Class